package com.aldobucchi.mxmlx
{
	
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	
	/**
	 *  
	 * 
	 *  @eventType mx.events.Event
	 */
	[Event(name="complete", type="flash.events.Event")]
	
	/**
	 *  
	 * 
	 *  @eventType mx.events.Event
	 */
	[Event(name="urlChanged", type="flash.events.Event")]
	
	/**
	 *  
	 * 
	 *  @eventType mx.events.Event
	 */
	[Event(name="nodeChanged", type="flash.events.Event")]

	/**
	 *  
	 * 
	 *  @eventType mx.events.Event
	 */
	[Event(name="stateChanged", type="flash.events.Event")]


	/**
	 * 
	 * Remote XML.
	 * Many times you find yourself in the need of downloading
	 * 
	 * 
	 * 
	 * @author aldo.bucchi@gmail.com
	 * 
	 */
	public class RXML extends FacelessComponentBase
	{
		
		public static const STATE_EMPTY		:int = 1;
		
		public static const STATE_LOADING	:int = 2;
		
		public static const STATE_LOADED	:int = 3;
		
		
		private var _url:String;
		[Bindable("urlChanged")]
		/**
		 * 
		 * The URL of the XML document to load.
		 * 
		 * @return 
		 * 
		 */		
		public function get url():String
		{
			return _url;
		}
		public function set url( v:String ):void
		{
			
			if ( _url == v )
				return;
				
			_url = v;
			
			urlChangedFlag = true;
			
			dispatchEvent( new Event( "urlChanged" ) );
		
			if ( autoLoad )
				load();
		}
	
		private var _node:XML = new XML("<root></root>"); // we start with an empty XML
		[Bindable("nodeChanged")]
		/**
		 * 
		 * After the document in the URL is loaded and parsed, this variable will
		 * contain the root node ( E4X XML object ) of the document.
		 * 
		 * @return 
		 * 
		 */		
		public function get node():XML
		{
			return _node;
		}
			
		
		private var _state:int = STATE_EMPTY;
		[Bindable("stateChanged")]
		public function get state():int
		{
			return _state;
		}
			
		
		private var _autoLoad:Boolean = true;
		/**
		 * 
		 * if set to true, loading will start as soon as a valid url is set or re-set.
		 * 
		 * @return 
		 * 
		 */		
		public function get autoLoad():Boolean
		{
			return _autoLoad;
		}
		public function set autoLoad( v:Boolean ):void
		{
			_autoLoad = v;
			if ( v == true && urlChangedFlag )
				load();
		}
		
		
		public var id2:String;
		

		private var urlChangedFlag:Boolean = false;

		
		private var loader:URLLoader;
		
		
		
		public function RXML()
		{
			loader = new URLLoader();
			loader.addEventListener( Event.COMPLETE, handleLoaderComplete );
		}
		
		
		
		/**
		 * Starts loading the given URL. If autoLoad is set to true this call is not necessary.
		 * 
		 */		
		public function load():void
		{
			if ( !_url )
				return;
			urlChangedFlag = false;
			// TODO: handle loader errors
			loader.load( new URLRequest( _url ) );
			setState( STATE_LOADING );
		}
		
		
		private function handleLoaderComplete( event:Event ):void
		{
			// TODO: handle XML parsing errors
			var xml:XML = XML( loader.data );
			_node = xml;
			dispatchEvent( new Event( "nodeChanged" ) );
			dispatchEvent( new Event( Event.COMPLETE ) );
			setState( STATE_LOADED );
			
		}
		
		private function setState( state:int ):void
		{
			if ( _state == state )
				return;
			_state = state;
			dispatchEvent( new Event("stateChanged") );
		}
		
		
		
		
		/**
		 * 
		 * Factory method to use this inline within databinding tags
		 * 
		 * @param url
		 * @return 
		 * 
		 */		
		public static function newInstance( url:String, autoLoad:Boolean = true ):RXML
		{
			var t:RXML = new RXML();
			t.url = url;
			
			if ( autoLoad )
				t.load();
			
			return t;
		}
		
		/**
		 * 
		 * Shortcut... identical to newInstance()
		 * 
		 * @return 
		 * 
		 */		
		public static function i( url:String, autoLoad:Boolean = true ):RXML
		{
			return newInstance( url, autoLoad );
		}
		
		
	}
	
	
}